//
//  LBRHTTPModule.m
//  LBReact
//
//  Created by WuShiHai on 19/5/24.
//  Copyright (c) 2019 Lebbay. All rights reserved.
//

#import "LBRRouterModule.h"

#import <LBFoundation/LBFoundation.h>
#import <LBRouter/LBRouter.h>

#import "LBRConstants.h"
#import "LBRViewController.h"
#import <React/RCTBridge.h>
#import <React/RCTBridge+Private.h>
#import <React/RCTModalHostViewController.h>
#import <React/RCTModalHostViewController.h>

#import "LBReactBridge.h"

@implementation LBRRouterModule
@synthesize bridge = _bridge;

- (void)dealloc {
    [[NSNotificationCenter defaultCenter] removeObserver:self];
}
- (instancetype)init {
    if (self = [super init]) {
        [[NSNotificationCenter defaultCenter] addObserver:self
                                                 selector:@selector(willStartLoadingJavaScript)
                                                     name:RCTJavaScriptWillStartLoadingNotification
                                                   object:nil];
        [[NSNotificationCenter defaultCenter] addObserver:self
                                                 selector:@selector(willStartLoadingModuleJavaScript:)
                                                     name:LBJavaScriptWillStartLoadingModuleNotification
                                                   object:nil];
    }
    return self;
}

- (void)willStartLoadingJavaScript {
    
}

- (void)willStartLoadingModuleJavaScript:(NSNotification *)notification {

}

+ (BOOL)requiresMainQueueSetup {
    return YES;
}

- (dispatch_queue_t)methodQueue {
    return dispatch_get_main_queue();
}

RCT_EXPORT_MODULE(router);

RCT_EXPORT_METHOD(openURL:(NSString *)URLString){
    [LBRouter openURL:URLString];
}

RCT_EXPORT_METHOD(close:(NSString *)moduleId){
    beginExecInMainBlock
    if (moduleId.length <= 0) {
        return;
    }
    //只考虑邻近两个window中的
    LBRViewController *module = [self findLatestReactViewController:moduleId];
    if (module) {
        NSArray<UIViewController *> *viewControllers = module.navigationController.viewControllers;
        if (viewControllers.count > 0) {
            NSMutableArray<UIViewController *> *new_viewControllers =  [NSMutableArray arrayWithArray:viewControllers];
            [new_viewControllers removeObjectAtIndex:[viewControllers indexOfObject:module]];
            module.navigationController.viewControllers = [new_viewControllers copy];
        }
    }
    endExecInMainBlock
}

RCT_EXPORT_METHOD(popWithModuleId:(NSString *)moduleId){
    beginExecInMainBlock
    if (moduleId.length <= 0) {
        return;
    }
    //只考虑邻近两个window中的
    LBRViewController *module = [self findLatestReactViewController:moduleId];
    if (module) {
        [module.navigationController popViewControllerAnimated:YES];
    }
    endExecInMainBlock
}

- (LBRViewController *)findLatestReactViewController:(NSString *)moduleId {
    //只考虑邻近两个window中的
    UIViewController *vc = [UIApplication displayViewController];
    __block UIViewController *module = nil;
    [vc.navigationController.viewControllers enumerateObjectsUsingBlock:^(__kindof UIViewController * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
        if ([obj isKindOfClass:[LBRViewController class]]
            && [[(LBRViewController *)obj moduleId] isEqualToString:moduleId]) {
            module = obj;
        }
    }];
    
    if (!module) {
        vc = [UIApplication displayViewController:vc.presentingViewController
                                    ignorePresent:YES];
        [vc.navigationController.viewControllers enumerateObjectsUsingBlock:^(__kindof UIViewController * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
            if ([obj isKindOfClass:[LBRViewController class]]
                && [[(LBRViewController *)obj moduleId] isEqualToString:moduleId]) {
                module = obj;
            }
        }];
    }
    return module;
}

RCT_EXPORT_METHOD(pop){
    [[UIApplication displayViewController].navigationController popViewControllerAnimated:YES];
}

RCT_EXPORT_METHOD(popWithType:(NSUInteger)type number:(NSUInteger)number) {
    UIViewController *vc = [UIApplication displayViewController];
    if (type == 1) {
        NSUInteger loopCount = 0;
        while (vc.presentingViewController && loopCount < number) {
            vc = vc.presentingViewController;
            loopCount++;
        }
        [vc dismissViewControllerAnimated:YES
                               completion:nil];
    } else {
        NSArray *viewControllers = vc.navigationController.viewControllers;
        if (viewControllers.count > number) {
            [vc.navigationController popToViewController:[viewControllers objectAtIndex:viewControllers.count - number - 1]
                                                animated:YES];
        } else {
            [vc.navigationController popToRootViewControllerAnimated:YES];
        }
    }
}

RCT_EXPORT_METHOD(openURLWithCallback:(NSString *)URLString
                  callback:(RCTResponseSenderBlock)callback) {
    [LBRouter openURL:URLString
           completion:^(LBRouterType type, NSString *URLString, NSString *paths, NSDictionary *userInfo) {
        LBBlockSafeRun(callback, @[]);
    }];
}

RCT_EXPORT_METHOD(popWithTypeCallback:(NSUInteger)type
                  number:(NSUInteger)number
                  callback:(RCTResponseSenderBlock)callback) {
    beginExecInMainBlock
    UIViewController *vc = [UIApplication displayViewController];
    if (type == 1) {
        NSUInteger loopCount = 0;
        while (vc.presentingViewController && loopCount < number) {
            vc = vc.presentingViewController;
            loopCount++;
        }
        [vc dismissViewControllerAnimated:YES
                               completion:^{
                                    LBBlockSafeRun(callback, @[]);
                               }];
    } else {
        NSArray *viewControllers = vc.navigationController.viewControllers;
        if (viewControllers.count > number) {
            [vc.navigationController popToViewController:[viewControllers objectAtIndex:viewControllers.count - number - 1]
                                                animated:YES];
        } else {
            [vc.navigationController popToRootViewControllerAnimated:YES];
        }
        LBBlockSafeRun(callback, @[]);
    }
    endExecInMainBlock
}

RCT_EXPORT_METHOD(registerRouter:(NSString *)router){
    if ([self.bridge.parentBridge isKindOfClass:[LBBridge class]]) {
        [(LBBridge *)self.bridge.parentBridge addCompnent:router];
    }
}

RCT_EXPORT_METHOD(displayModuleId:(RCTResponseSenderBlock)callback){
    UIViewController *displayViewController = [UIApplication displayViewController];
    if ([displayViewController isKindOfClass:[LBRViewController class]]) {
        NSString *moduleId = [(LBRViewController *)displayViewController moduleId];
        LBBlockSafeRun(callback, @[moduleId ?: @""]);
    } else if ([displayViewController isKindOfClass:[RCTModalHostViewController class]]) {
        UIViewController *vc = displayViewController.presentingViewController;
        if (![vc isKindOfClass:[RCTModalHostViewController class]]
            && ![vc isKindOfClass:[LBNavigationController class]]) {
            vc = [UIApplication displayViewController:vc
                                        ignorePresent:YES];
        } else {
            while ([vc isKindOfClass:[RCTModalHostViewController class]]
                   || [vc isKindOfClass:[LBNavigationController class]]) {
                vc = [UIApplication displayViewController:vc
                                            ignorePresent:YES];
                if ([vc isKindOfClass:[LBRViewController class]]) {
                    //手动结束
                    break;
                } else {
                    vc = vc.presentingViewController;
                }
            }
        }
        
        if ([vc isKindOfClass:[LBRViewController class]]) {
            NSString *moduleId = [(LBRViewController *)vc moduleId];
                LBBlockSafeRun(callback, @[moduleId ?: @""]);
        } else {
            LBBlockSafeRun(callback, @[]);
        }
    } else{
        LBBlockSafeRun(callback, @[]);
    }
}

@end
